package org.xxpay.pay.channel.hulpay;

import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Service;
import org.xxpay.core.common.constant.MchConstant;
import org.xxpay.core.common.constant.PayConstant;
import org.xxpay.core.common.util.JsonUtil;
import org.xxpay.core.common.util.MyLog;
import org.xxpay.core.entity.PayOrder;
import org.xxpay.pay.channel.BasePayNotify;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

/**
 * @author: pangxiaoyu
 * @date: 2020年4月14日14:44:34
 */
@Service
public class HulpayPayNotifyService extends BasePayNotify {

    private static final MyLog _log = MyLog.getLog(HulpayPayNotifyService.class);
    private static final String logPrefix = "【处理"+ HulpayConfig.CHANNEL_NAME+"支付回调】";

    @Override
    public String getChannelName() {
        return HulpayConfig.CHANNEL_NAME;
    }

    @Override
    public JSONObject doNotify(Object notifyData) {
        _log.info("====== 开始处理{}支付回调通知 ======", getChannelName());
        HttpServletRequest request = (HttpServletRequest) notifyData;
        JSONObject retObj = buildRetObj();
        Map<String, String> payContext = new HashMap();

        String respString = HulpayConfig.RETURN_VALUE_ERROR;
        try {
            PayOrder payOrder = verifyPayParams(request, payContext);
            if( payOrder == null ) { //验证参数失败
                retObj.put(PayConstant.RESPONSE_RESULT, HulpayConfig.RETURN_VALUE_ERROR);
                return retObj;
            }
            //订单已经支付完成
            if(payOrder.getStatus() == PayConstant.PAY_STATUS_SUCCESS || payOrder.getStatus() == PayConstant.PAY_STATUS_COMPLETE){
                retObj.put(PayConstant.RESPONSE_RESULT, HulpayConfig.RETURN_VALUE_SUCCESS);
                return retObj;
            }
            //上游通知 状态
            String channelOrderNo = payContext.get("queryId"); //上游订单号

            int updatePayOrderRows = commonService.payOrderService.updateStatus4Success(payOrder.getPayOrderId(), channelOrderNo);
            if (updatePayOrderRows != 1) {
                _log.error("{}更新支付状态失败,将payOrderId={},更新payStatus={}失败", logPrefix, payOrder.getPayOrderId(), PayConstant.PAY_STATUS_SUCCESS);
                retObj.put(PayConstant.RESPONSE_RESULT, "处理订单失败");
                return retObj;
            }
            _log.error("{}更新支付状态成功,将payOrderId={},更新payStatus={}成功", logPrefix, payOrder.getPayOrderId(), PayConstant.PAY_STATUS_SUCCESS);
            payOrder.setStatus(PayConstant.PAY_STATUS_SUCCESS);

            // 业务系统后端通知
            baseNotify4MchPay.doNotify(payOrder, true);
            _log.info("====== 完成处理{}支付回调通知 ======", getChannelName());
            respString = HulpayConfig.RETURN_VALUE_SUCCESS;
        } catch (Exception e) {
            _log.error(e, logPrefix + "处理异常");
        }
        retObj.put(PayConstant.RESPONSE_RESULT, respString);
        return retObj;
    }

    /**
     * 验通知参数
     * @return
     */
    public PayOrder verifyPayParams(HttpServletRequest request, Map<String, String> payContext) {
        // 获取数据
        JSONObject json = null;
        try {
            String data = URLDecoder.decode(request.getParameter("data"), "UTF-8");
            // json转换
            json = JsonUtil.getJSONObjectFromJson(data);
        } catch (UnsupportedEncodingException e) {
            _log.error(e, logPrefix + "回调解析异常");
        }
        // 校验结果是否成功
        String amount = json.getString("amount");                  // 订单金额 分
        String payorderid = json.getString("payorderid");          // 平台订单号
        String merid = json.getString("merid");                    // 商户号
        String order = json.getString("order");		                // 商户订单号
        String status = json.getString("status");                  // 订单状态
        String merrmk = json.getString("merrmk");                  // 商户备注
        String sign = json.getString("sign"); 		                // 签名

        _log.info("[{}]amount={}, payorderid={}, merid={}, order={}, status={}, merrmk={}, sign={}",
                logPrefix, amount, payorderid, merid, order, status, merrmk, sign);

        // 验证状态
        if (!"1".equals(status)) {
            _log.error("状态错误 ,payOrderId={}, status={}", order, status);
            return null;
        }

        // 查询payOrder记录
        String payOrderId = order;
        PayOrder payOrder = commonService.payOrderService.findByPayOrderId(payOrderId);
        if (payOrder == null) {
            _log.error("Can't found payOrder form db. payOrderId={}, ", payOrderId);
            return null;
        }

        HulpayConfig hulpayConfig = new HulpayConfig(getPayParam(payOrder));
        // 验证签名
        Map<String, Object> paramMap = new TreeMap();
        // 接口类型
        paramMap.put("amount", amount);
        paramMap.put("payorderid", payorderid);
        paramMap.put("merid", merid);
        paramMap.put("order", order);
        paramMap.put("status", status);
        paramMap.put("merrmk", merrmk);
        String signValue = HulpayUtil.getSign(paramMap, hulpayConfig.getKey());
        if(!sign.equals(signValue)) {
            _log.error("验证签名失败. payOrderId={}, ", payOrderId);
            return null;
        }
        payContext.put("queryId", payorderid);
        return payOrder;
    }

    public static void main(String args[]) throws UnsupportedEncodingException {
        String yyy  ="%7B%22amount%22%3A%221000%22%2C%22merid%22%3A%221001000000299%22%2C%22merrmk%22%3A%22%22%2C%22order%22%3A%22P01202007061730551910044%22%2C%22payorderid%22%3A%223805578718381056%22%2C%22sign%22%3A%2223b69a2340886db3044296dd479925f9%22%2C%22status%22%3A%221%22%7D";
        String string = URLDecoder.decode( yyy, "UTF-8" );
        System.out.println(string);
    }

}
